A debugger allows you to debug the program.
You can set break points, run the program till it hits a breakpoint, single step the program, and examine the value of variables & registers when the program is not running.
An ICD (In Circuit Debugger) is a debugger that runs code on the target.
A simulator is a debugger that runs code on a simulation of a target.
An ICD2 is both a programmer and an ICD.
There are a lot of people who do quite well without a ICD. However Wekipedia says
The importance of a good debugger cannot be overstated. Indeed, the existence and quality of such a tool for a given language and platform can often be the deciding factor in its use, even if another language/platform is better-suited to the task.
That's pretty well it - ones like the ICD2 use special features of the processor, which costs you a couple of I/O pins. Professional ones use special chips (at HUGE!!! expense) which don't have this limitation.