They are all close in meaning.
I'll add a few things to what's already said exaggerating the slight nuance differences.
1. 구분하다: distinguish/separate something, in a controlled and systematic way.
2. 구별하다: distinguish, tell apart, in a more general sense.
3. 분간하다: tell apart, including the most primitive sense.
Examples (with the best choices indicated):
- 읽은 책을 읽을 책과 구분[12]했다: I separated the books I read from those yet to read.
- 기차에 흡연석과 금연석이 구분[12]되어 있었다: The train had smoking and non-smoking seats separated.
- 일의 공과 사는 구분[12]하여야 한다: You must differentiate your duty from private matters.
- 어떤 옷에는 남녀 구별[21]이 없다: Some garments have no gender distinction.
* 색맹 테스트에서 색깔을 구별[2]해야 했다: I had to tell colors apart for color blindness test.
- 진짜 지폐와 위조 지폐의 분간[32]이 어렵다: It's hard to tell apart real and counterfeit notes.
- 그의 말이 장난인지 진심인지 분간[3]할 수 가 없다: I can't tell whether he's joking or serious.
* 약을 먹었더니 꿈인지 생시인지 분간[3]이 안 됐다: Taking the drug made it hard to tell reality from a dream.