Can you have memory leaks in managed code? Yes!
Most developers think for a little while, mention the garbage collector and pinvoke, RCW calls to unmanaged code. But when pushed on a purely managed code situation the answers tend to be less sure.
If you think of memory leaks as an application not properly releasing objects when they are no longer needed then just keeping a reference to a no longer used object is a good example, and the garbage collector won't help here. There are other ways, such as blocking the finalizer thread for example. Dan Crevier talks about an automated way to detect leaks and how they used used the technqiue when developing Microsoft Max.
Rico Mariani has a more details post on tracking down managed memory leaks, showing you how to use Windbg, CLR Profiler and the SOS (Son of Strike) debugger extension. The SOS extension isn't for everyday debugging, fortunately Mike Taulty of Microsoft UK has a great video nugget showing how it works.
Don't forget either the Improving .NET application performance and scalability patterns and practices book I've mentioned before as an essential read.
Another MSDN article on production debugging of .NET framework applications explains how to determine if you have a leak in managed or unmanaged code:
Native Memory Consumption
If the Private Bytes counter in Perfmon increases while the .NET # of Bytes in all Heaps counter stays flat, this is evidence of native memory consumption.
Managed Memory Consumption
When using Perfmon, if both the Private Bytes counter and the .NET # of Bytes in all Heaps counter increase at the same rate, this is evidence of managed memory consumption. Look at the size of allocated managed memory and consider what the GC is doing. When looking at the dump file, use SOS commands to list the managed heap size and compare it to the total size of the dump file. Consider what details you can learn about the large object heap and the generations. Look to see if large objects (85 KB or more) or smaller objects consume most of the memory. If it's the former, look at the details of the large object heap. If it's the latter, consider what generations 0, 1, and 2 contain. For large objects, determine if they are rooted, and whether or not they should be rooted. If they aren't rooted, they are candidates for collections. Determine if they are eventually collected properly.
Whilst on the subject of debugging, I hadn't noticed this little tip of pressing Ctrl whilst viewing a DataTip in Visual Studio 2005 (or press the middle mouse wheel) to make it transparent so you can see the code underneath.