## brainfuck, 94 bytes

    +[[<+>>+<-]++[>-<------]>-[>]<<[>>+>]>,]++++++++++[[[<]<]+[-[>[.>]]<[<]>+[>]>]<<
    .[<<[<]>-]++>]

Formatted:

    +
    [
      [<+> >+<-]
      ++[>-<------]>-[>]
      <<[>>+>]
      >,
    ]
    ++++++++++
    [
      [[<]<]
      +
      print
      [
        -[>[.>]]
        <[<]
        >+[>]
        >
      ]
      <<.
      increment
      [
        <<[<]
        >-
      ]
      ++>
    ]

Expects input of the form `9,10,11` without a trailing newline, and outputs subsets in the same format, sometimes with a trailing comma. The first line printed will always be empty, signifying the empty set.

[Try it online.](http://brainfuck.tryitonline.net/#code=K1tbPCs-Pis8LV0rK1s-LTwtLS0tLS1dPi1bPl08PFs-Pis-XT4sXSsrKysrKysrKytbW1s8XTxdK1stWz5bLj5dXTxbPF0-K1s-XT5dPDwuWzw8WzxdPi1dKys-XQ&input=MSwyMyw0LDU)

The basic idea is to place a bit next to each element, then repeatedly increment the binary number while printing the corresponding subset before each increment. (A bit indicates whether an element is in the subset.) A sentinel bit to the left of the array is used to terminate the program. This version actually creates an exponential number of sentinels to save some bytes; a more efficient 99-byte solution that only uses one sentinel can be found in the revision history.

Each bit is encoded as one plus its value; i.e., it can be either `1` or `2`. The tape is laid out with the bit before each element and a single zero cell between adjacent elements. The comma is included on the tape for non-final elements, so that we don't need to do anything special to print delimiters.