It's a simple question but doesn't have a simple answer. (Or rather, I haven't the understanding and skill to give a clear answer.) But I'll try.
Parallel processing has been going on a long time, and today, we have things like GPUs, vector units in processors, multi-threaded software, speculative execution, multiple cores, and more.
Some problems cannot be solved in a parallel manner, but many things can. Some things can be partially solved in a parallel manner, but accuracy or other concerns may suffer.
- Are any modern apps truly single-core? I don't think so. At least not well-built apps. The GUI runs on its own thread, and any longer-running (i.e. not instant) tasks should be run on their own threads. Not every app follows this, but I would say any significant app (i.e. anything more complicated than a fart app and has actual users) does. Very large and old apps might be too costly to update - but you said modern, so they don't count.
- I don't think any app is single core. Ultimately almost all tasks are serial, but most apps built as per my answer above, can respond to events and do multiple things. You can read your mail while it is checking or sending mail. You can organize your media while iTunes is playing a song, or downloading the latest podcast episode. Many CPU-bound tasks (i.e. transcoding video in Handbrake) actually use up all your cores.
- In the worst case where your app is entirely a single thread, each app runs in its own memory space, and so, yes, the CPU will schedule it to run simultaneously and independently of other apps. Which naturally means it will be scheduled to an unoccupied or less busy core.
Yes, the OS absolutely benefits from multiple cores. The computer is doing tons of things simultaneously: processing inputs from many sources (networks, sensors, peripherals, storage, energy-monitoring devices, and traditional inputs like keyboards and mice) and generating lots of output (the same I/O devices above, plus your monitor), and many of these tasks happen independently of each other. The OS is like a traffic cop that makes sure everyone can get through that busy intersection without running into each other.
The one downside of multithreaded operations is that you sometimes can't really draw an honest thermometer-style progress bar, because any sub-task can take an unpredictable amount of time, or, it may simply be far too much overhead to track the time taken by each subtask.
Mac OS X dealt with this early on. The startup progress bar was changed to a fake progress bar (i.e. 50% does not mean 50% done booting up). They'd animate the bar to move really slow, and stop around 50% or 90%, but do some aqua-like animation so the user didn't think it was frozen. When it finished booting up, they'd hurry that bar to 100%, and note the time the boot up took. Next time it would use that saved boot up time figure to move the fake progress bar along more smoothly.
If you ever see a bar that moves slowly, and then stall, or jump to completion, now you know why!
There's true multitasking and there's fake multitasking too! Where a process can be split into different tasks, and the tasks don't have dependencies, then they can run at the same time. Large tasks (video transcode) can be broken down into individual tasks that might benefit from being run at the same time (decode, gather statistics, try several different compression styles on the same block, pick the winner).
Where you can't multitask, you can fake it too, with speculative execution. Where there's a branch in the logic (if X, then A, else B) you can pre-do the work for A and B on separate execution units even before you know what X is. When X arrives, you throw away the result you don't need.
For true multitasking code, computer language improvements like async/await (.net) have changed what once was a cumbersome or very difficult set of code to write, almost trivial to do so now. So I think a lot of software will get less buggy and more efficient, and be far easier to maintain.