The core idea is that mapM maps an "action" (ie function of type a -> m b) over a list and gives you all the results as a m [b]. mapM_ does the same thing, but never collects the results, returning a m ().
If you care about the results of your a -> m b function (ie the bs), use mapM. If you only care about the effect, whatever it is, but not the resulting value, use mapM_ because it can be more efficient and, more importantly, makes your intentions clear.
You would always use mapM_ with functions of the type a -> m (), like print or putStrLn. These functions return () to signify that only the effect matters. If you used mapM, you'd get a list of () (ie [(), (), ()]), which would be completely useless but waste some memory. If you use mapM_, you would just get a (), but it would still print everything.
On the other hand, if you do care about the returned values, use mapM. As a hypothetical example, imagine a function fetchUrl :: Url -> IO Response—chances are, you care about the response you get for each URL. So for this, you'd use mapM to get a lists of responses out that you can then use in the rest of your code.
So: mapM if you care about the results and mapM_ if you don't.
Normal map is something different: it takes a normal function (a -> b) instead of one using a monad (a -> m b). This means that it cannot have any sort of effect besides returning the changed list. You would use it if you want to transform a list using a normal function. map_ doesn't exist because, since you don't have any effects, you always care about the results of using map.