Probably the things I wrote that get the most use are image chipping and embedding components for the Navy's Maritime Domain Awareness system, all of the updated security labeling for the NRO's first-level ground processing, many of the Jenkins pipeline libraries used for development automation within GEOINT programs, and some ETL scrapers for the APIs of various project management systems to pull into a corporate metrics warehouse.
I started out in my mid-30s when I went back to school for Applied Math, originally intending to try for the Army's ORSA program, as Applied Math for most of the past 50 years has inevitably involved a lot of computer programming, then simultaneously discovered I liked programming even more than I liked math, and I wasn't going to be able to stay in the Army thanks to spinal degeneration, so switched to Computer Science.
That said, I'm still largely self-taught anyway. School only goes so far, and most courses expect you to come in already knowing how to do the basics. That involved the same steps to learn anything else, lots and lots of practice. Some books, mostly the C/C++ classics by K&R and Stroustrup, some supplemental courses on specific applications and technology stacks I found in Coursera, and ultimately making my own toy Linux distro with its own package manager and configuration management system after going through Linux From Scratch a bunch of times and getting tired of all the manual steps.
Really, though, how to make anything "meaningful" was mostly learned on the job. Other than I guess tiny utilities that are part of a standard GNU or BSD system, there isn't a whole lot of meaningful software written by one person. Most of it exists for decades and is worked on by hundreds of people who may not even be alive at the same time. Unless you're contributing to some really big OSS project like Linux or Kubernetes, it's hard to get that kind of experience outside of being employed.
That's probably largely due to language choice, though. C and C++ are very mature languages that have been around a long time. No matter what you might want to do with them, chances are a library that provides the bulk of the building blocks you need already exists, thanks to the GNU project, libc specification, OpenSSL, curl, Boost, QuantLib, Armadillo, so many decades of prior work and the fact they've been the major working languages used in universities and research labs. Developers coming up in the JavaScript and Rust ecosystems these days face a more greenfield world where the opportunity to make smaller reusable components still exists, plus the web is inherently a less stable platform than OS APIs, and both of those are less stable than implementing math algorithms that have been known for centuries, so the situation is different there.