This is a case of, "in theory there is no difference between theory and practice, ..."
Usually, applications interact with operating system's network stack using an abstraction, called sockets. Sockets, which is also some sort of object that is maintained inside the operating systems, contain necessary information.
If this is the case, then why does the UDP datagram header contain a space for a source port?
a UDP header must contain these values. Your OS (or implementation of network stack) can choose when to set these values.
I frankly speaking do not think that it works like described, and instead OS requires you to specify local address for a socket, before you can send packet through the socket.
But here is a plausible explanation, why it can work like this. Source addres is determined by routing function. You can have several network interfaces, each of which has different source address. Then your host can be configured to send packets to one set of destinations to one address and another set of destinations to another address. Then, you can't really set source address, before the decision of routing is done. In this case network layer will have to set the values in the headers.
update
actually, sorry, that quote does not make sense.
The transport layer encapsulates the application layer data along with destination IP and destination port information and passes it along to the network layer.
ports only exist at transport layer, so transport layer definitelly does not pass destination port to the network layer. it passes destination (and potentially source) ip address, but not port.
Note that no information about the source IP or source port is included.
a source port is assigned before a packet can be sent. if the source port is not specified by an application, OS will just select one and put it into the header. This actually works the same with TCP. When you initiate a connection, you specify destination port, and source port is randomly selected for you.
end update
My other question is that since after each layer from the OSI model headers get stripped (frames -> packets -> segments -> finally just data at the application level), how does the application layer know what IP to respond to if the IP header has been stripped?
Operating system/network stack has to provide you with this information, and how it does this depends on the socket API. Here is a link to linux man page for recvfrom, check the second function.
In general, layers communicate with each other, and when a lower layer strips packet header, it can still pass all the necessary information from that header to the upper layer. How this is done, is specific to how the network stack in question is implemented. But it has to be done and it can't work otherwise.
write
will flow back up the network stack getting the appropriate layers added on the way. (there are various function calls to get the various bits of upper layer information if the app needs it.)