I use this, it wraps onto multiple lines and indents by the length of user@host so it assumes the current PS1 is effectively '\u@\h:\w$'. It does not truncate the path, and it adapts to the current terminal width. It only splits the path on /, so it doesn't elegantly deal with really long directories (but it does preserve spaces for selection/copy). It makes sure you always have at least a 20 character space available for input.
readonly _PS1="${PS1}" 2>/dev/null
function myprompt()
{
    local IFS
    local nn nb pbits xpwd="" ww=60 len=0 pp='\\w\$ '
    local indent uh="${LOGNAME}@${HOSTNAME//.*/}"
    test -n "$COLUMNS" && let ww=$COLUMNS-20  # may be unset at startup
    PS1="${_PS1}"
    if [ ${#PWD} -ge $ww ]; then
        printf -v indent "%${#uh}s%s" " " "> "  # indent strlen(user@host)
        IFS=/ pbits=( $PWD ); unset IFS
        nb=${#pbits[*]}
        for ((nn=1; nn<nb; nn++)) {
            if [ $(( $len + 1 + ${#pbits[$nn]} )) -gt $ww ]; then
                xpwd="${xpwd}/...\n${indent}..."
                len=0
            fi
            xpwd="${xpwd}/${pbits[$nn]}"
            let len=len+1+${#pbits[$nn]}
        }
        # add another newline+indent if the input space is too tight
        if (( ( ${#uh} + len ) > ww )); then
            printf -v xpwd "${xpwd}\n%${#uh}s" " " 
        fi 
        PS1="${PS1/$pp/$xpwd}$ "    
    fi
}
PROMPT_COMMAND=myprompt
This works by taking the magic \w (matches only \w$ for this) out of PS1 and replacing it with $PWD, then wrapping it as a plain string of characters. It recomputes PS1 each time from the original value which is saved in _PS1, this means "invisible" escapes are preserved too, my full original prompt string for xterm and bold prompt:
PS1="\[\033]0;\u@\h:\w\007\]\[$(tput bold)\]\u@\h\[$(tput sgr0)\]:\w$ "
And the end result in an 80 column terminal:
mr@onomatopoeia:~$ cd /usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/Perf/Trace
mr@onomatopoeia:/usr/src/linux/tools/perf/scripts/perl/Perf-Trace-Util/lib/...
               > .../Perf/Trace$ _
This works from bash-3.2 as printf -v var is used. Due to various complexities it will need some adjustment for other variations of PS1.
(The path in the xterm title bar is neither wrapped nor abbreviated, something which could be done by incorporating one of the other answers here into the above function.)