There is another useful call to add to your code,
diffstate.DumpStatistics();<br />
That should tell you of the things that remain allocated between the first checkpoint and the second checkpoint.
Now from previous notes, you should realize that not all "still allocated" objects / memory are "leaks". It might simply be some object that you are still using. For example, my application caches data read from a file. If I were to take the checkpoint before reading the data and then check for "leaks", the cached data would appear as "still allocated". Is that a "leak", no because I know about it and it was part of the design.
So use the "DumpStatistics" after your TRACE message to see what memory is still allocated. If you have the default DEBUG_NEW allocation, you should also see the module and line number where that memory was allocated. You might even be able to double-click on the output and Visual Studio should take you to the line where the allocation / new occurred.