A salt just needs to be unique to avoid attacks, e.g. attacks using rainbow tables. It may be public, so in that sense it is fine to send it with messages or during some kind of handshake protocol. If multiple messages need to be encrypted then a handshake with a salt makes most sense. That way it would at least not have to be transmitted out of band. The good thing of large random salts is mainly that you don't need to keep any state.
A salt doesn't need to be randomly generated. However, normally you would want to change the salt for each session. If there already is some kind of session identifier then that can be used as salt, possibly together with the ID's of the sender and receiver included (generally you'd use different keys for sender and receiver, even if the keys are symmetric).
If you would allow asymmetric primitives then there are of course options such as Diffie-Hellman key agreement, where the derived key is just used for authentication. It might be a good idea to use some kind of double ratchet or similar where the key depends both on key agreement and a password derived key. That way a bad password would not directly influence the security of the key, unless DH gets broken. There are also more efficient PAKE protocols such as SRP available if you'd allow asymmetric primitives.
Notes:
- If you can agree on a secret, high entropy salt then you might as well agree on a symmetric master key and skip the password based derivation altogether.
- Beware that you do need a separate IV if you want to encrypt multiple messages with the same key. If CBC is used then the IV needs to be unpredictable (randomized).
- Usually you'd derive 4 keys a la TLS. One for encryption, one for MAC but for sending messages in both directions. That way it is impossible to replay messages to the sender - without that being detected anyway. You'd first derive a master session key, and derive the other session keys from that using HKDF or a similar KBKDF.