There are broadly 4 ways:
Build Seniority
If you're happy with your current company and want to stay there, a good way to be able to demand more is to become the senior resident expert at a vital technology and/or internal code base. I've watched people do this at several companies I've worked at. They became so obviously and publicly super-productive and good at what they do (and the thing they do was important) that they naturally gained a "senior" status - even without necessarily getting team leading or managerial responsibility per se.
I can only presume that they had more ammunition to ask for better raises at performance review time, and for some I knew for a fact that they were better paid than average.
Also, see this answer.
Change Employers
This is essentially this answer. You have to be careful with this one though. Lots of very short stints don't look good on a CV, even if there are reasonably good explanations for the moves. For contracts with fixed terms, it's not so bad, but you don't want to have a whole string of permanent salaried positions on your CV that are all under 1-2 years or so. 3-4 years and up is probably okay though, as an average.
Go Contracting/Consulting
This one is, in a way, Change Employers on steroids. If you find a good niche which has a shortage of qualified engineers and quite a bit of short term project work that needs doing, this can be an excellent option. But it's quite a different mindset and lifestyle than having normal permanent salaried jobs (I've never done it personally, but I've known lots of people who did).
Vertical Movement
I know you asked about "programmer salary", but it still feels like this is obligatory to mention. Rising to team leader and/or management roles is always a possible option. Note that this is often tied with the first option (Gain Seniority), but it doesn't always have to be. Sometimes it's a natural byproduct of being at a company long enough, taking ownership of things you were working on, and knowing all the people and processes well.