Accessing 2 dimensional array in PROGMEM inside loop
After going through link given by Juraj above again, I could make it work as follows:

const byte a1[] PROGMEM = {'a', 'b', 'c', 'd'};
const byte a2[] PROGMEM = {'e', 'f', 'g', 'h', 'i'};
const byte a3[] PROGMEM = {'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q'};
const byte a4[] PROGMEM = {'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};

const byte * const arr[] PROGMEM = {a1, a2, a3, a4};

void setup() {
  Serial.begin(74880);

  Serial.println(pgm_read_byte(&amp;(arr[0][0])));
  Serial.println(pgm_read_byte(&amp;(arr[1][0])));
  Serial.println(pgm_read_byte(&amp;(arr[2][0])));
  Serial.println(pgm_read_byte(&amp;(arr[3][0])));
  for (int i = 0; i &lt; 4; i++) {
    Serial.print(i);
    Serial.print(":");
    Serial.println(pgm_read_byte_near(pgm_read_word(&amp;(arr[i])) + 0));
  }
  int j = 0;
  Serial.println(pgm_read_byte(&amp;(arr[j][0])));
  j = 1;
  Serial.println(pgm_read_byte(&amp;(arr[j][0])));
  j = 2;
  Serial.println(pgm_read_byte(&amp;(arr[j][0])));
  j = 3;
  Serial.println(pgm_read_byte(&amp;(arr[j][0])));
}

void loop() {

}


Now it shows the expected output and access from inside loop using variable index is possible. Thanks.