STM32F4 USART not correctly configured
It turns out that the code was fine, and it was all hardware issues. Firstly, the USART2 TX/RX pins on that board's connector are by design not connected to anything. The MCU pins are only connected to the ST-Link. (There are solder bridges to change this configuration.) So that's why I didn't get anything on the scope.

As for why I didn't get any data on the USB port, I think the ST-Link was not compatible with USB 3.0. When I upgraded its firmware, suddenly I saw my data.