Great solution by jippie. I'd like to elaborate a bit on it.
The schematic:

The idea is to make one of the I/Os output and the other two input which allows you to read the state of two buttons. Three times output \$\times\$ two inputs is good for 6 buttons as the schematic shows.
How do I activate the output? Make it high? Let's do it for pin 1, then diodes B and F are forward biased, so we'd expect to be able to read those buttons. For many microcontrollers this won't work. Pressing button B will make input 2 high, but what if the button isn't pressed? The input would be floating, and then you can't read anything meaningful on it. A pull-down resistor would help, but many microcontrollers only have pull-up resistors, and then you'll never read a low level. I don't know about all of them, but at least a number of AVR and PIC microcontrollers only have pull-ups.
In that case the right way is to activate the internal pull-ups and activate the output by making it low. We're not controlling buttons B and F, but A and E. If button A is not pressed the pull-up will make input 2 high. Press button A and you pull the input low.
The algorithm:
IO2 = input, pull-up enabled
IO3 = input, pull-up enabled
IO1 = output, low
Button_A = IO2 (low = pressed)
Button_E = IO3 (low = pressed)
IO1 = input, pull-up enabled
IO2 = output, low
Button_B = IO1 (low = pressed)
Button_C = IO3 (low = pressed)
IO2 = input, pull-up enabled
IO3 = output, low
Button_F = IO1 (low = pressed)
Button_D = IO3 (low = pressed)
As far as I know all NXP Cortex-M controllers, for instance, have both configurable pull-up/pull-down resistors. For those you can use positive logic (high = pressed) if you use the pull-downs, and an active high output. Note that you will read different buttons for the same output:
IO2 = input, pull-down enabled
IO3 = input, pull-down enabled
IO1 = output, high
Button_B = IO2 (high = pressed)
Button_F = IO3 (high = pressed)
IO1 = input, pull-down enabled
IO2 = output, high
Button_A = IO1 (low = pressed)
Button_D = IO3 (low = pressed)
IO2 = input, pull-down enabled
IO3 = output, high
Button_E = IO1 (low = pressed)
Button_C = IO3 (low = pressed)