I have a CS degree, but I had to teach myself the theory due to my school's sad excuse for professors.
Here are the two things I did that taught me the most about programming: learning how operating systems and programming languages work, and writing a raytracer and a software rasterizer.
The former two put all my years of tinkering on computers into perspective. The latter tested my programming and problem solving skills in a novel way. Both made me more well rounded as a developer. Not to mention they were extremely satisfying!!