You've got a lot of different answers, here, so I want to raise a question in your head instead: what, exactly, are you categorizing as math? I have been an academic, an engineer, and a backend-and-frontend web developer. As an academic, many of the professional mathematicians that I know cannot count a tip. One of the better definitions that I know of what they do is "creating art out of abstract patterns themselves." But computers are defined in terms of their manipulation of abstract symbols, so any programming is in this sense some form of mathematics. More on that in a little bit. So the question is, what do you mean by "math" here?

Do you mean calculation? Then you need to understand how exponents work, the ballpark figure that 2^10 is about 10^3, that there are roughly 10^5 seconds in a day, roughly 10^-1 seconds in your reaction time, and roughly 10^9 things that your computer can do per second. So continuous things need to happen in less than 100 million operations, and, say, an O(n^2) algorithm will top out at sizes where n is around 10,000. That's the sort of arithmetic that you'll want to keep in your head, the mathematics of exponents. The computer will handle explicit calculations for you, but rules of thumb are unbeatable.

Maybe you mean the more "engineering math" topics. Some pieces of combinatorics may help you -- at minimum, knowing that if N people at a party shake hands, there are N * (N - 1) / 2 handshakes, which is also the number of cells above the diagonal in an NxN matrix and the sum of the integers from 1 to N - 1. (All of this should make sense if you stare at it long enough.) This simple principle underlies the "birthday paradox" math, that if you start randomly selecting values out of N, you'll start to see random collisions (selecting the same value) when k^2 / 2 is approximately N, or k = sqrt(2N). So, for example, you know that if you have a playlist with 50 songs on it, the gap between repeated songs is usually about 30 minutes (sqrt(2 * 50) * 3 minutes / song), and you'll need a smarter shuffle if you want it to be closer to the (3 minutes) * 50 = 150 minutes that some users may be expecting.

You should ideally also pick up factorials (and maybe Stirling's approximation of them), choose-functions, and the trick of randomly partitioning B balls into G groups by looking at binary strings pretending that 0's are balls and 1's are group partitions, hence the strings are of length B + G - 1 and the number of strings is the same as choosing B out of B + G - 1. Those sorts of patterns come up in a lot of different programming contexts, especially because a good hacker can often live by the axiom, "try brute force first" -- knowing these rules will help you know how bad your programs are with respect to scaling.

A lot of engineering trickery is obscenely useful when you're writing computer programs, too: for example, engineers learn that when they know the form of something but not the exact expression, they should make sure that the "edge case" lines up. The simplest example is when you're counting up on a 0-indexed array, what's the last element you read? If you've not memorized it, just say, "oh, if the array had one element, the last index I'd read is index 0, so the exact form must be `n - 1`." If you're programming a rotation, you might say, "Oh, this thing needs to be something like r * [± cos t, ± sin t] ... but which one is the cosine, which is the sine, are any of them plus or minus?" you can answer this question pretty quickly if you know what the answer is for t = 0, where sin t = 0 and cos t = 1.

Somewhere at the border between engineering math and true math is linear algebra. You do not need linear algebra in all circumstances, but it can enrich many circumstances and is required for a lot of them. If you're doing graphics, physics, simulations, probability/statistics, solving simple equations, or trying to solve linear relations, the techniques learned in a first-year linear algebra course will be invaluable and some of the vocabulary will stick with you.

The fundamental ideas of calculus -- like "let's tweak the inputs a little and see how the outputs change, maybe it's roughly linear", or "why don't I store this as a list of differences between adjacent elements?" can be quite helpful, and in fact the "derivative" operation has a powerful analogue in functional programming (a data structure's "zipper" turns out to be its derivative), and occasionally you actually need to optimize things, but this is less applicable than other branches of mathematics.

Is what you mean by "math" more abstract than calculus? At that even more abstract level we get some serious goodies. It turns out that there is a deep connection between mathematical models of the integers and useful data structures, if you can figure that out. Various algebras can be super-helpful, for example the patch-commutation algebra in the Darcs version control system, and the relational algebra underlying SQL. Learning a bit of lambda calculus can help you understand things on a whole new level. Finally, some basic thinking about propositional logic can really help to elevate your knowledge above simple boolean expressions, so that you can start to think of "foralls" and "there-exists" symbols, especially when you start to talk about type theories or logic programing.

More important than all of that, in my experience, is really knowing your languages from the ground up. You don't need to be any of these to be a copy-paste programmer: copy a file which does something like what you want, tweak some parameters which look interesting, constantly monitoring the output of the program until it passes the tests that you want to accomplish. That's going to be the most common job out there. But if you know your language's operators and reserved words and syntactic forms in-and-out, you can do something far better -- abstraction -- which will make your code far more useful in the end. But the thing is, if mathematics is making art out of patterns themselves, then programming language design is also, somewhere, a field of mathematics: and learning this is a sort of "math", too. There is a "math" of parsing. You can even find libraries of "parser combinators" -- you might want to watch some talks explaining how those work. Similarly, there is a "math" to really understanding pointers and graph traversals and such.

I've seen people who have your "10 years of experience" and have never seen any of those things and don't really understand, for example, JavaScript's scope rules. They write fairly good code, but it can often be much, much smaller -- and faster and easier to maintain. So to me, that's the key first step. Understand a couple different languages from the ground-up, and how they approach the world.