а ты просто на код смотрел или во время выполнения подсчет ссылок произвел?
Вы уже обнаружили проблему, но значительно ухудшили ее, вызвав Controls.Clear(). Экстра-специально противно, потому что сборщик мусора не будет завершать элементы управления, которые удаляются таким образом. После создания собственного дескриптора окна для элемента управления он будет ссылаться на внутреннюю таблицу, которая отображает ручки Window для элементов управления. Только уничтожение собственного окна удаляет ссылку из этой таблицы. Этого никогда не бывает в коде вроде этого, вызов Dispose() - это жесткое требование. Очень необычно в .NET.