R, 239239 230 bytes
function(s){K=table(el(strsplit(gsub(" ","",sscan(,"")),"")))
L=sum;m=matrix(" ",L<-sum(K|1)+1
M=,M<-(M=max(K))+-M%%5+1
m=matrix(" ",L,M)
m[2;m[2:L,M]=names(K)
m[1;m[1,M-g]=paste0(g<-c(1,seq(5,M,5)),"-")
m[1;m[1,]=format(m[1,],j="r")
for;for(X in 2:L)m[X,M-1:K[X-1]]="X"
write1]]=0;write(m,1,L,,"")}
table
does the heavy lifting here, uniquifying the characters, sorting them, and returning their counts.
Everything else is just ensuring the offsets are right for printing, which is the "real" work of an ascii-art challenge.
Thanks to @dylnan for pointing out a bug.
Thanks to @rturnbull for the scan
approach, dropping 2 bytes.