I added a math degree to my CS degree (which also added a year, but I was going to be a year late graduating anyways). So I took a lot of courses in math my last two years. The three that made the biggest difference for me were:
Set theory: Covered proof construction in a deeper fashion than high school geometry and was the first proof-heavy math course I had taken in college (others used them and expected regurgitation, but did not expect construction; this was my first math-major only course).
Later I took both Abstract Algebra and Linear Algebra (high level) together. I wasn't struggling in either, but in my mind they were two separate courses. One day we were doing a proof in Linear and I realized I'd already done it in Abstract, only we had been dealing with (I don't recall what) some other objects than matrices or vectors. What I realized then was that we were dealing (in both classes) with a class of objects and operations on them that were the same in the abstract, but different in the concrete (if you wanted to actually apply the math to solve a problem). Given the right perspective, I could apply the proofs of one to the other so long as the objects had the same properties the proofs relied on. Both classes became a breeze after that because, coincidentally, the order the material was covered in meant that every other week one class had been largely covered by the other when viewed in this fashion.