How are programs written into a microcontroller? What role does JTAG play?
The ATmega µC series has various means to program it:


Self-programming. That's what the bootloader does. It loads data e.g. through the UART interface into RAM, then flashes the non-bootloader flash memory pages.
Parallel programming. Traditional method, you need a pretty special programming tool to do that. Only required when you disabled ISP programming because you wanted to use the RESET pin as a GPIO pin. Requires to remove the µC from the circuit.
ISP programming. That's the simplest method, requires a simple tool which you can easily build yourself, and some free programming software (avrdude). Sometimes requires to remove the µC from the circuit, but designers may take care when assigning GPIOs to avoid that.
DebugWire. ISP on steroids. Uses only the RESET pin, needs a fairly complex tool and a proprietary software until recently. Almost never requires to remove the µC from the circuit because the RESET pin usually is just that, RESET.


JTAG in contrary is a "standard" protocol and interface definition which can be used with a great number of chips. The original intention was to fill the flipflops representing the internal state of a device from outside. It's a testing interface. Nowadays it can be and is used for flash programming, too. The programming software needs to know every single thing how to program the specific chip, there's no standard for that.

Apart from the self-programming, all these programming methods are hard-wired into the chips. The earliest versions of JTAG have been nothing more than a 1000s-stages shift register.